﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Expect.Core.Fixtures;
using Expect.Core.Errors;
using Microsoft.VisualStudio.TestTools.UnitTesting;
//using MakeSure = NUnit.Framework.Assert;
using Expect.Core.Test.Fixtures;
//using NUnit.Framework.SyntaxHelpers;

namespace Expect.Core.Test
{
    using Expect.Core.BaseClasses;
    using Expect.Core.Interfaces;

    [TestClass]
    public class ColumnFixtureTest
    {
        [TestMethod]
        public void ColumnFixture_column_not_found()
        {
            SpecificationDefinition test = new SpecificationDefinition();
            test.AddFixture<ColumnFixtureImpl>()
                .WithRow("col1", "col2", "mycol3", "sum()")
                .WithRow("1", "2", "3", "6")
                .WithRow("4", "5", "6", "15")
                .WithRow("7", "8", "9", "24");

            
            DefaultSpecificationExecution runner = new DefaultSpecificationExecution();
            runner.Run(this, test);
            Assert.IsFalse(test.IsSuccessful);
            Assert.IsTrue(test.HasError<ElementNotFoundError>(e => e.Kind == ElementKind.PropertyOrField));
        }

        [TestMethod]
        public void ColumnFixture_method_not_found()
        {
            SpecificationDefinition test = new SpecificationDefinition();

            FixtureDefinition definition = new FixtureDefinition<ColumnFixtureImpl>(test)
                .WithRow("col1", "col2", "col3", "mysum()")
                .WithRow("1", "2", "3", "6")
                .WithRow("4", "5", "6", "15")
                .WithRow("7", "8", "9", "24");

            test.Add(definition);

            DefaultSpecificationExecution runner = new DefaultSpecificationExecution();
            runner.Run(this, test);
            Assert.IsFalse(test.IsSuccessful);
            Assert.IsTrue(test.HasError<ElementNotFoundError>(e => e.Kind == ElementKind.Method));
        }

        [TestMethod]
        public void ColumnFixture_invalid_format()
        {
            SpecificationDefinition test = new SpecificationDefinition();

            FixtureDefinition definition = new FixtureDefinition<ColumnFixtureImpl>(test)
                .WithRow("col1", "col2", "col3", "sum()", "anothermethod()")
                .WithRow("1", "2", "3", "6")
                .WithRow("4", "5", "6", "15")
                .WithRow("7", "8", "9", "24");

            test.Add(definition);

            DefaultSpecificationExecution runner = new DefaultSpecificationExecution();
            runner.Run(this, test);
            Assert.IsFalse(test.IsSuccessful);
            Assert.IsTrue(test.HasError<InvalidFixtureFormatError>());
        }

        [TestMethod]
        public void ColumnFixture_execute_generic()
        {
            SpecificationDefinition test = new SpecificationDefinition();

            FixtureDefinition definition = new FixtureDefinition<ColumnFixtureImpl>(test);
            definition.WithRow("col1", "col2", "col3", "sum()");
            definition.WithRow(1, 2, 3, 6);
            definition.WithRow(4, 5, 6, 15);
            definition.WithRow(7, 8, 9, 24);

            test.Add(definition);

            DefaultSpecificationExecution runner = new DefaultSpecificationExecution();
            runner.Run(this, test);
            if (!test.IsSuccessful)
            {
                Assert.Fail(test.GetMessageForFailedResult());
            }
        }

        [TestMethod]
        public void ColumnFixture_execute_inline()
        {
            SpecificationDefinition test = new SpecificationDefinition();

            test.AddFixture()
                .WithRow("ColumnFixtureImpl")
                .WithRow("col1", "col2", "col3", "sum()")
                .WithRow("1", "2", "3", "6")
                .WithRow("4", "5", "6", "15")
                .WithRow("", "5", "6", "15")
                .WithRow("", "", "6", "15")
                .WithRow("7", "8", "9", "24");

            DefaultSpecificationExecution runner = new DefaultSpecificationExecution();
            runner.Run(this, test);
            if (!test.IsSuccessful)
            {
                Assert.Fail(test.GetMessageForFailedResult());
            }
            //MakeSure.That(test.Status.Success, Is.True);
        }

        [TestMethod]
        public void ColumnFixture_execute_inline_with_alias()
        {
            SpecificationDefinition test = new SpecificationDefinition();

            test.AddFixture()
                .WithRow("a column fixture with alias")
                .WithRow("col1", "col2", "col3", "sum()")
                .WithRow("1", "2", "3", "6")
                .WithRow("4", "5", "6", "15")
                .WithRow("", "5", "6", "15")
                .WithRow("", "", "6", "15")
                .WithRow("7", "8", "9", "24");

            DefaultSpecificationExecution runner = new DefaultSpecificationExecution();
            runner.Run(this, test);
            if (!test.IsSuccessful)
            {
                Assert.Fail(test.GetMessageForFailedResult());
            }
            //MakeSure.That(test.Status.Success, Is.True);
        }

        [TestMethod]
        public void ColumnFixture_execute_inline_WithContextPreset()
        {
            IExecutionContext ctx = new DefaultExecutionContext();
            SpecificationDefinition test = new SpecificationDefinition();
            test.Context = ctx;
            ctx.Container = this;

            test.AddFixture()
                .WithRow("ColumnFixtureImpl")
                .WithRow("col1", "col2", "col3", "sum()")
                .WithRow("1", "2", "3", "6")
                .WithRow("4", "5", "6", "15")
                .WithRow("7", "8", "9", "24");

            Assert.IsTrue(test.IsSuccessful);
            //MakeSure.That(test.Status.Success, Is.True);
        }

        [TestMethod]
        //[ExpectedException(typeof(ValueMismatchException))]
        public void ColumnFixture_failure()
        {
            SpecificationDefinition test = new SpecificationDefinition();

            FixtureDefinition definition = new FixtureDefinition<ColumnFixtureImpl>(test)
                .WithRow("col1", "col2", "col3", "sum()")
                .WithRow("1", "2", "3", "12")
                .WithRow("4", "5", "6", "15")
                .WithRow("7", "8", "9", "24");

            test.Add(definition);

            DefaultSpecificationExecution runner = new DefaultSpecificationExecution();
            runner.Run(this, test);
            Assert.IsFalse(test.IsSuccessful);
            Assert.IsTrue(test.HasError<ValueMismatchError>());
        }
    }
}
